
#ifndef __USERBOOT_H__
#define __USERBOOT_H__

//===============================================头文件声明======================================================//
#include "SWM341.h"
#include "load_file.h"

//=================================================宏定义========================================================//
//#define UB_SECURE_AES_ENABLE //是否在 UserBoot 中添加及使用 AES 加密算法(由于是软件实现, 会带来一定的运行时间损耗)<待调_暂不可用>

// UserBoot 引导启动标志(uint32_t) 枚举
#define GO_APP 				(0x12345678) //运行固件
#define EXEC_UPDATE 		(0x23456789) //更新固件(检测到有可更新的固件)
#define BACKUP_RESTORE 		(0x3456789A) //恢复固件(从备份中)

//================================================类型声明=======================================================//
typedef int (*data_code_cb)(const void *src_buff, void *dst_buff, uint32_t bytes); //数据加密/解密回调

//================================================变量声明=======================================================//
// 存放至本地 (SPI-Flash) 的固件文件名
extern const char *const Firmware_Name_Update;
extern const char *const Firmware_Name_Backup;
// 本地磁盘类型
extern const disk_t Firmware_Disk;

//================================================函数声明=======================================================//
/**
 * @brief	UserBoot 功能
 * @param	/
 * @retval	/
 * @note	本函数会一直阻塞在被调用处, 之后的语句都不会得到执行
 */
void userboot(void);

/**
 * @brief	跳转至 UserBoot 执行对应动作
 * @param	boot_flag : UserBoot 引导启动标志(详见对应枚举)
 * @retval	/
 * @note	/
 */
void jump_to_userboot(uint32_t boot_flag);

/**
 * @brief	固件下载 (外部 => 本地)
 * @param	src_path	- 外部固件绝对路径
 *			dst_path	- 本地固件绝对路径
 * @param	data_enc 	- 数据加密回调
 * @retval	0-success	非0-error code
 * @note	须保证对应磁盘的 FAT 文件系统处于挂载状态
 */
uint8_t firmware_download(const char *src_path, const char *dst_path, data_code_cb data_enc);

/**
 * @brief	数据加密
 * @param	src_buff  	: 数据源
 * @param	dst_buff 	: 输出流
 * @param	bytes 		: 数据量( AES 分组长度 128 bit == 16 Bytes, 数据量必须被该长度整除)
 * @retval	0-success	非0-error code
 * @note	使用 芯片唯一 96 bit ID 实现加密算法: 对称 - AES, 非对称 - RSA/ECC, 哈希 - MD5<不可还原>
 */
int data_encode(const void *src_buff, void *dst_buff, uint32_t bytes);

/**
 * @brief	数据解密
 * @param	src_buff  	: 数据源
 * @param	dst_buff 	: 输出流
 * @param	bytes 		: 数据量( AES 分组长度 128 bit == 16 Bytes, 数据量必须被该长度整除)
 * @retval	0-success	非0-error code
 * @note	依据 数据加密规则 data_encode() 逆向进行解码
 */
int data_decode(const void *src_buff, void *dst_buff, uint32_t bytes);

#endif //__USERBOOT_H__